package natappvip.liujinliang.thread;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import natappvip.liujinliang.service.FileSourceService;
import natappvip.liujinliang.service.impl.FileSourceServiceImpl;
import natappvip.liujinliang.util.FileHandler;

/**
 * @ClassName:  Solver   
 * @Despt: 线程间合作完成文件存储  
 * @Auth: Liujinliang 
 * @Date: 2018年7月24日 下午10:37:29
 */
public class Solver {
	
	private File file;	// 待保存文件
	
	private int N;	// 线程数目

	private CyclicBarrier barrier;
	
	private FileSourceService service = new FileSourceServiceImpl();
	
	private static Logger logger = LoggerFactory.getLogger(Solver.class);
	
	public Solver() {
	}

	public Solver(int threadNum, File file) {
		this.file = file;
		N = threadNum;
	}

	class Save implements Runnable {
		
		private String tmpFileName;	// 临时文件名称
		
		public Save() {
		}
		
		public Save(String tmpFileName) {
			this.tmpFileName = tmpFileName;
		}

		@Override
		public void run() {
			
			// 创建临时文件
			File metaDataFile = new File(tmpFileName);	
			if (!metaDataFile.exists()) {
				try {
					metaDataFile.createNewFile();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			logger.info("临时文件{}创建成功", tmpFileName);
			
			for (int i = 0; i < 10; i++) {
				service.save(file); // 向临时文件写数据
			}
			logger.info("临时文件{}已成功写入数据", tmpFileName);
			
			try {
				barrier.await();
			} catch (InterruptedException ex) {
				return;
			} catch (BrokenBarrierException ex) {
				return;
			}
		}
	}
	
	public void paralleSave() throws InterruptedException {
		Runnable barrierAction = new Runnable() { 
			@Override
			public void run() {
				
				// 将临时文件的元信息写入 mdata.txt
				try {
					
					for (int seq = 0; seq < N; seq++ ) {
						
						FileHandler.copy(
								new FileReader("mdata" + (seq + 1) + ".txt"), 
								new FileWriter("mdata.txt", true));
					}
					
					logger.info("临时文件合并成功");
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				
				// 删除临时文件
				for (int seq = 0; seq < N; seq++) {
					File file = new File("mdata" + (seq + 1) + ".txt");
					if (file.exists()) {
						logger.info("临时文件{}删除成功", file.getName());
						file.delete();
					}
				}
			}

		};
		barrier = new CyclicBarrier(N, barrierAction);
		
		List<Thread> threads = new ArrayList<Thread>(N);
		
		// 创建线程（创建临时文件mdatai.txt、存储文件uuid、记录文件元信息到临时文件）
		for (int i = 0; i < N; i++) {
			Thread thread = new Thread(new Save("mdata" + (i + 1) + ".txt"));
	        threads.add(thread);
	        logger.info("线程{}创建成功", thread.getName());
	        thread.start();
	     }

	    // wait until done
	    for (Thread thread : threads)
	    {
	    	thread.join();
	    }
	    
	}
	
}
